package cn.jiedanba.itext5.gm.sign;

import com.itextpdf.text.pdf.*;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;

/**
 * 签名删除
 */
public class DeleteSignature {

    /**
     * 删除最后一个签名
     *
     * @param pdf
     * @return
     */
    public byte[] lastSignature(byte[] pdf) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            PdfReader reader = new PdfReader(pdf);
            PdfStamper stamper = new PdfStamper(reader, bos, '\0', true);
            PRAcroForm pRAcroForm = reader.getAcroForm();
            AcroFields acroFields = stamper.getAcroFields();
            if (acroFields.getSignatureNames() == null || acroFields.getSignatureNames().size() == 0) {
                throw new RuntimeException("无签名可删除");
            }
            int signatureFieldCount = acroFields.getSignatureNames().size();

            int indRef = 0;

            String lastSignatureFieldName = acroFields.getSignatureNames().get(signatureFieldCount - 1);
            acroFields.clearSignatureField(lastSignatureFieldName);

            PdfArray fields = pRAcroForm.getAsArray(PdfName.FIELDS);
            if (fields != null) {
                for (int i = fields.size() - 1; i >= 0; i--) {
                    PdfIndirectReference fieldRef = fields.getAsIndirectObject(i);
                    PdfDictionary fieldDict = (PdfDictionary) PdfReader.getPdfObject(fieldRef);
                    if (PdfName.SIG.equals(fieldDict.getAsName(PdfName.FT))) {
                        if (fieldDict != null && fieldDict.contains(PdfName.T)) {
                            PdfString fieldName = fieldDict.getAsString(PdfName.T);
                            if (fieldName != null && fieldName.toString().equals(lastSignatureFieldName)) {
                                indRef = fieldDict.getIndRef().getNumber();
                                fieldDict.clear();
                                fields.remove(i);
                                stamper.markUsed(fieldDict);
                                stamper.markUsed(fields);
                            }
                        }
                    }
                }

            }
            for (int j = 1; j <= reader.getNumberOfPages(); j++) {
                PdfDictionary pdfDictionary = reader.getPageN(j);
                PdfArray pdfArray2 = pdfDictionary.getAsArray(PdfName.ANNOTS);
                if (pdfArray2 != null) {
                    for (byte b = 0; b < pdfArray2.size(); b++) {
                        PdfDictionary pdfDictionary1 = pdfArray2.getAsDict(b);
                        if (indRef == pdfDictionary1.getIndRef().getNumber()) {
                            pdfArray2.remove(b--);
                            stamper.markUsed(pdfDictionary);
                            stamper.markUsed(pdfArray2);

                        }
                    }
                }
            }
            stamper.markUsed(pRAcroForm);
            stamper.markUsed(reader.getCatalog());
            stamper.close();
            reader.close();
            return bos.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("删除最后一个签名异常", e);
        }
    }

    /**
     * 删除所有签名
     *
     * @param pdf
     * @return
     */
    public byte[] allSignature(byte[] pdf) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            PdfReader reader = new PdfReader(pdf);
            PdfStamper stamper = new PdfStamper(reader, bos);

            AcroFields acroFields = stamper.getAcroFields();
            if (acroFields.getSignatureNames() == null || acroFields.getSignatureNames().size() == 0) {
                throw new RuntimeException("无签名可删除");
            }
            ArrayList<String> fields = acroFields.getSignatureNames();
            for (String string : fields) {
                acroFields.removeField(string);
            }
            stamper.close();
            reader.close();
            return bos.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("删除所有签名异常", e);
        }
    }
}
